﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Mobwiz.SpellChecker.Core
{
    public class GenericDictionaryGenerator : IDictionaryGenerator
    {
        private bool _disposed = false;

        private Dictionary<string, List<string>> dictSet;
        public Dictionary<string, List<string>> DictionarySet
        {
            get { return dictSet; }
        }

        public event EventHandler<ConvertProgressChangedEventArgs> ConvertProgressChanged;
        public event EventHandler ConvertCompleted;

        public IPhonet Phonet
        {
            get;
            set;
        }

        public GenericDictionaryGenerator(IPhonet phonet)
        {
            this.Phonet = phonet;
        }

        ~GenericDictionaryGenerator()
        {
            Dispose(false);
        }

        /// <summary>
        /// Read the word from the word list, and store them in the dictionary set.
        /// </summary>
        /// <param name="wordListFilePath"></param>
        /// <param name="destFilePath"></param>
        public void StartConvert(string wordListFilePath)
        {
            ReadWords(wordListFilePath);
        }

        private void ReadWords(string wordListFilePath)
        {
            dictSet = new Dictionary<string, List<string>>(20000);

            string code;
            int curline, curpos, newpos, total = 0;

            using (TextReader tr = new StreamReader(wordListFilePath))
            {
                string[] lines = tr.ReadToEnd().Split(new char[] { '\n' });
                total = lines.Count();

                curline = 0;
                curpos = 0;

                foreach(var line in lines)
                {               
                    curline++;
                    newpos = (int)(((float)curline / (float)total) * 100);
                    if (newpos > curpos)
                    {
                        curpos = newpos;
                        OnConvertProgressChanged(line.Trim(), curline, total);
                    }

                    code = this.Phonet.Transform(line.Trim());

                    if (dictSet.Keys.Contains(code))
                    {
                        (dictSet[code] as List<string>).Add(line.Trim());
                    }
                    else
                    {
                        dictSet.Add(code, new List<string>(new string[] { line.Trim() }));
                    }
                }
                tr.Close();
            }
        }

        protected void OnConvertProgressChanged(string word, int current, int total)
        {
            if (ConvertProgressChanged != null)
            {
                ConvertProgressChanged(this, new ConvertProgressChangedEventArgs(word, current, total));
            }
        }

        protected void OnConvertCompleted()
        {
            if (ConvertCompleted != null)
            {
                ConvertCompleted(this, new EventArgs());
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }

        

        protected void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    this.dictSet.Clear();
                    this.dictSet = null;
                }

                _disposed = true;
            }
        }
    }
}
